class WxRequest {
  defaluts = {
    baseURL:'',
    url:'',
    data:null,
    method:'GET',
    header:{
      "Content-type":'application/json'
    },
    timeout:60000,
    isLoading:true // 控制是否默认使用loading
  }
  // 定义拦截器对象
  interceptors = {
    request:(config)=>config,
    response:(response)=>response
  }
  // 定义数组队列，用于存储请求队列，存储请求标识
  queue=[]

  // 用于创建和初始化类的属性和方法
  constructor(params={}){
    this.defaluts = Object.assign({},this.defaluts,params)
  }
  // request实例方法接收一个对象类型的参数
  // 属性值和wx.request方法调用时传递的参数保持一致
  request(options){
    this.timerId && clearTimeout(this.timerId)

    options.url = this.defaluts.baseURL + options.url
    options = {...this.defaluts,...options}

    if(options.isLoading && options.method!=='UPLOAD'){
    // 在请求发送之前，添加loading效果
    // wx.showLoading()
    // 判断queue队列是否为空，如果为空，就显示loading
    this.queue.length===0 && wx.showLoading()
    // 然后立即向queue数组队列中添加请求标识
    this.queue.push('request')
    }

    // 在请求发送之前，调用请求拦截器，新增和修改请求参数
    options = this.interceptors.request(options)

    return new Promise((resolve,reject)=>{
      if(options.method==='UPLOAD'){
        wx.uploadFile({
          ...options,
          success:(res)=>{
            // 需要将服务器返回的JSON字符串转为对象
            res.data = JSON.parse(res.data)
            // 合并参数
          const mergeRes =  Object.assign({},res,{config:options,isSuccess:true})
          resolve(this.interceptors.response(mergeRes))
          },
          fail:(err)=>{
            // 合并参数
          const mergeErr =  Object.assign({},err,{config:options,isSuccess:false})
          reject(this.interceptors.response(mergeErr))
          }
        })
      }else {
        wx.request({
          ...options,
          success:(res)=>{
            // 不管成功还是失败，都需要调用响应拦截器
            const mergeRes = Object.assign({},res,{config:options,isSuccess:true})
            resolve(this.interceptors.response(mergeRes))
          },
          fail:(err)=>{
             // 不管成功还是失败，都需要调用响应拦截器
            const mergeErr = Object.assign({},err,{config:options,isSuccess:false})
            reject(this.interceptors.response(mergeErr))
          },
          // 接口调用结束的回调函数（调用成功、失败都会执行）
          complete:()=>{
            if(options.isLoading){
            // 在每个请求结束以后，都会执行complete
            // 每次从queue队列中删除一个标识
            this.queue.pop()
            // 删除标识后，需要判断目前queue数组是否为空
            // 如果为空，说明请求发送完成了
            this.queue.length===0 && this.queue.push('request')
            this.timerId=setTimeout(()=>{
              this.queue.pop()
              this.queue.length===0 && wx.hideLoading()
              clearTimeout(this.timerId)
            },1)
            }
          }
        })
      }
    })
  }
  // 封装GET实例方法
  get(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'GET'},config))
  }
    // 封装DELETE实例方法
    delete(url,data={},config={}){
      return this.request(Object.assign({url,data,method:'DELETE'},config))
    }
      // 封装PUT实例方法
  put(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'PUT'},config))
  }
    // 封装POST实例方法
    post(url,data={},config={}){
      return this.request(Object.assign({url,data,method:'POST'},config))
    }
    // 用来处理并发请求
    all(...promise){
      // 通过展开运算符接收传递的参数
      // 那么展开运算符会将传入的参数转为数组
      return Promise.all(promise)
    }
    // upload实例方法，用来对wx.uploadFile进行封装
    uploadFile(url,filePath,name='file',config={}){
      return this.request(
        Object.assign({url,filePath,name,method:'UPLOAD'},config)
      )
    }
}

export default WxRequest